home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / UNIX / TREEPAR / NETWORK.C < prev    next >
C/C++ Source or Header  |  1992-11-23  |  21KB  |  1,109 lines

  1. /* network.c - read and write the network files
  2.  *
  3.  * 28.Jul.87  jimmc  Initial definition
  4.  *  1.Aug.87  jimmc  Add filename arg to NPlot
  5.  *  2.Aug.87  jimmc  Fill in code for nets
  6.  * 12.Aug.87  jimmc  Make some routines not static, add NCreate routines
  7.  * 14.Aug.87  jimmc  Add Globals stuff
  8.  * 22.Sep.87  jimmc  Use xalloc.h stuff
  9.  *  3.Nov.87  jimmc  Add rowdir
  10.  *  6.Nov.87  jimmc  xalloc, xrealloc changed: remove (char *)NULL arg
  11.  * 18.Jan.88  jimmc  Use TFhandle and TkHandle instead of casts
  12.  * 26.Jan.88  jimmc  Output backslash before outputting double quotes
  13.  * 27.Jan.88  jimmc  Add feedthrough stuff
  14.  * 29.Feb.88  jimmc  Improve robustness when doing partial place/route
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <ctype.h>
  19. #include <strings.h>
  20. #include "xalloc.h"
  21. #include "network.h"
  22. #include "tklex.h"
  23. #include "tfile.h"
  24. #include "plot.h"
  25.  
  26. extern char *index();
  27. extern char *strsav();
  28.  
  29. Nbase *NCurBase;
  30. static Nbase *Tbase;
  31. static Nnet *Tnet;
  32. static Ngroup *Tpath;
  33. TFhandle Thandle;
  34.  
  35. char Tflag[256];
  36. int Tflagcount = sizeof(Tflag)/sizeof(Tflag[0]);
  37.  
  38. char Tflagr[256+1];
  39.  
  40. /* VARARGS2 */
  41. fileerror(handle,fmt,a0,a1,a2)
  42. TkHandle handle;
  43. char *fmt;
  44. char *a0, *a1, *a2;
  45. {
  46. char buf[1200];
  47.  
  48.     sprintf(buf,fmt,a0,a1,a2);
  49.     fprintf(stderr,"Line %d: %s\n",TkLineNumber(handle),buf);
  50. }
  51.  
  52. static expand(group,size)
  53. Ngroup *group;        /* group to expand */
  54. int size;        /* size of each item in the array, in bytes */
  55. {
  56.     if (group->count>=group->alloc) {    /* need more space */
  57.         if (group->alloc==0) group->alloc = 15;
  58.         else group->alloc *= 2;
  59.         if (group->d.x) group->d.x =
  60.             (char **)xrealloc((char *)group->d.x,group->alloc*size);
  61.         else group->d.x = (char **)xalloc(group->alloc*size);
  62.     }
  63. }
  64.  
  65. insertp(group,item)
  66. Ngroup *group;
  67. char *item;
  68. {
  69.     expand(group,sizeof(char *));
  70.     group->d.x[group->count++] = item;
  71. }
  72.  
  73. removep(group,item)
  74. Ngroup *group;
  75. char *item;
  76. {
  77. int cct,i;
  78.  
  79.     cct = group->count;
  80.     for (i=cct-1; i>=0; i--) { /* find it in list */
  81.         if (group->d.x[i]==item) {
  82.             if (i<cct-1) {
  83.                 group->d.x[i] = group->d.x[cct-1];
  84.             }
  85.             group->count--;
  86.             return;
  87.         }
  88.     }
  89. }
  90.  
  91. /* Name routines */
  92.  
  93. NDumpString(f,s)
  94. FILE *f;
  95. char *s;
  96. {
  97.     if (!s) {
  98.         fprintf(f,"\"\"");
  99.         return;
  100.     }
  101.     fputc('"',f);
  102.     for (;*s;s++) {
  103.         if (*s=='"') fputs("\\\"",f);
  104.         else if (isprint(*s)) fputc(*s,f);
  105.         else if (*s=='\n') fputs("\\n\\\n",f);
  106.         else fprintf(f,"\\%03o",*s);
  107.     }
  108.     fputc('"',f);
  109. }
  110.  
  111. /* Bounding box routines */
  112.  
  113. int BBset;
  114. static Npoint BBlow,BBhigh;
  115.  
  116. NInitBB()
  117. {
  118.     BBset = 0;
  119.     BBlow.X = BBlow.Y = 0;
  120.     BBhigh.X = BBhigh.Y = 0;
  121. }
  122.  
  123. NAddBB(p)
  124. Npoint p;
  125. {
  126.     if (!BBset) {
  127.         BBlow.X = BBhigh.X = p.X;
  128.         BBlow.Y = BBhigh.Y = p.Y;
  129.         BBset++;
  130.     }
  131.     else {
  132.         if (p.X < BBlow.X) BBlow.X = p.X;
  133.         if (p.X > BBhigh.X) BBhigh.X = p.X;
  134.         if (p.Y < BBlow.Y) BBlow.Y = p.Y;
  135.         if (p.Y > BBhigh.Y) BBhigh.Y = p.Y;
  136.     }
  137. }
  138.  
  139. static struct _oposinfo {
  140.     char *text;
  141.     int icode;
  142. } OposTab[] = {
  143.     "N", N,
  144.     "S", S,
  145.     "E", E,
  146.     "W", W,
  147.     "NE", NE,
  148.     "NW", NW,
  149.     "SE", SE,
  150.     "SW", SW,
  151.     "C", C,
  152. };
  153. static int OposTabSize = sizeof(OposTab)/sizeof(OposTab[0]);
  154.  
  155. int NGetOposInt(s)
  156. char *s;
  157. {
  158. int i;
  159.  
  160.     for (i=0; i<OposTabSize; i++) {
  161.         if (strcmp(s,OposTab[i].text)==0) {
  162.             return OposTab[i].icode;
  163.         }
  164.     }
  165.     return -1;
  166. }
  167.  
  168. char *
  169. NGetOposString(n)
  170. int n;
  171. {
  172. int i;
  173.  
  174.     for (i=0; i<OposTabSize; i++) {
  175.         if (n==OposTab[i].icode) return OposTab[i].text;
  176.     }
  177.     return "??";
  178. }
  179.  
  180. /* Box routines */
  181.  
  182. Nbox *
  183. NCreateBox(name,originx,originy,sizex,sizey,text,textx,texty,textpos,
  184.     rownum,rowpos)
  185. char *name;
  186. int originx,originy;
  187. int sizex,sizey;
  188. char *text;
  189. int textx,texty;
  190. char *textpos;
  191. int rownum;
  192. int rowpos;
  193. {
  194. Nbox *box;
  195.  
  196.     box = XCALLOC(Nbox,1);
  197.     box->name = name;
  198.     box->origin.X = originx;
  199.     box->origin.Y = originy;
  200.     box->size.X = sizex;
  201.     box->size.Y = sizey;
  202.     box->text = text;
  203.     box->text_origin.X = textx;
  204.     box->text_origin.Y = texty;
  205.     box->text_opos = NGetOposInt(textpos);
  206.     box->rownum = rownum;
  207.     box->rowpos = rowpos;
  208.     insertp(&(Tbase->boxlist),(char *)box);
  209.     return box;
  210. }
  211.  
  212. NSetupBox(handle)
  213. TFhandle handle;
  214. {
  215.     TFSetup(handle,"box",NCreateBox,
  216.         "name.s","orgx.i","orgy.i","sizex.i","sizey.i",
  217.         "text.s","textx.i","texty.i","textpos.s",
  218.         "rownum.i","rowpos.i",0);
  219. }
  220.  
  221. NWriteBox(f,box,i)
  222. FILE *f;    /* file to write to */
  223. Nbox *box;    /* the box to write out */
  224. int i;        /* counter */
  225. {
  226.     if (!box) return;
  227.     if (i==0) {    /* write out the schema the first time */
  228.         fprintf(f,"\nbox schema (\"name.s\" \"sizex.i\" \"sizey.i\" \
  229. \"orgx.i\" \"orgy.i\"\n\t\"text.s\" \"textx.i\" \"texty.i\" \"textpos.s\" \
  230. \"rownum.i\" \"rowpos.i\")\n");
  231.     }
  232.     fprintf(f,"\nbox (");
  233.     NDumpString(f,box->name);
  234.     fprintf(f," %d %d %d %d ",box->size.X,box->size.Y,
  235.         box->origin.X,box->origin.Y);
  236.     NDumpString(f,box->text);
  237.     fprintf(f," %d %d \"%s\"",box->text_origin.X,box->text_origin.Y,
  238.             NGetOposString(box->text_opos));
  239.     fprintf(f," %d %d",box->rownum,box->rowpos);
  240.     fprintf(f,")\n");
  241. }
  242.  
  243. NBoundBox(box)
  244. Nbox *box;
  245. {
  246. Npoint p;
  247.     NAddBB(box->origin);
  248.     p.X = box->origin.X + box->size.X;
  249.     p.Y = box->origin.Y + box->size.Y;
  250.     NAddBB(p);
  251. }
  252.  
  253. NPlotBox(box)
  254. Nbox *box;
  255. {
  256.     if (RIsFeedBox(box)) {
  257.         if (Tflag['f'])
  258.             plotx(box->origin.X,box->origin.Y);
  259.         return;
  260.     }
  261.     PBox(box->origin.X,box->origin.Y,
  262.         box->origin.X+box->size.X, box->origin.Y+box->size.Y);
  263.     if (box->text) {
  264.         if (!Tflag['T']) { /* 'T' flag turns off box text */
  265.             PText(box->origin.X+box->text_origin.X,
  266.                 box->origin.Y+box->text_origin.Y,
  267.                 box->text_opos,box->text);
  268.         }
  269.         if (Tflag['l']) {    /* 'l' flag puts in label instead */
  270.             PText(box->origin.X+box->text_origin.X,
  271.                 box->origin.Y+box->text_origin.Y,
  272.                 box->text_opos,box->name);
  273.         }
  274.     }
  275. }
  276.  
  277. Nbox *
  278. NFindBox(base,name)
  279. Nbase *base;
  280. char *name;        /* name of the box to find */
  281. {
  282. int i;
  283.  
  284.     for (i=0; i<base->boxlist.count; i++) {
  285.         if (strcmp(base->boxlist.d.box[i]->name,name)==0)
  286.             return base->boxlist.d.box[i];
  287.     }
  288.     return 0;
  289. }
  290.  
  291. NIFreeBox(box)
  292. Nbox *box;
  293. {
  294.     removep(&(Tbase->boxlist),(char *)box);
  295.     NFreeBox(box);
  296. }
  297.  
  298. NFreeBox(box)
  299. Nbox *box;
  300. {
  301.     if (box->name) tfree(box->name);
  302.     if (box->text) tfree(box->text);
  303.     tfree(box);
  304. }
  305.  
  306. NClearBoxConns(box)
  307. Nbox *box;
  308. {
  309.     box->connlist.count = 0;
  310. }
  311.  
  312. /* Net routines */
  313.  
  314. Nnet *
  315. NCreateNet(name,rownum)
  316. char *name;
  317. {
  318. Nnet *net;
  319.  
  320.     net = XCALLOC(Nnet,1);
  321.     net->name = name;
  322.     net->rownum = rownum;
  323.     Tnet = net;    /* for future path input */
  324.     Tpath = 0;
  325.     insertp(&(Tbase->netlist),(char *)net);
  326.     return net;
  327. }
  328.  
  329. NSetNet(net)
  330. Nnet *net;
  331. {
  332.     Tnet = net;
  333.     Tpath = 0;
  334. }
  335.  
  336. NCreate1Path(x0,y0,x1,y1)
  337. int x0,y0;
  338. int x1,y1;
  339. {
  340.     NCreatePath(x0,y0);
  341.     NCreatePath(x1,y1);
  342.     NCreateEndPath();
  343. }
  344.  
  345. NCreatePath(x,y)
  346. int x,y;
  347. {
  348.     if (!Tnet) return;
  349.     if (!Tpath) {
  350.         Tpath = XCALLOC(Ngroup,1);
  351.         insertp(&(Tnet->pathlist),(char *)Tpath);
  352.     }
  353.     expand(Tpath,sizeof(Npoint));
  354.     Tpath->d.pt[Tpath->count].X = x;
  355.     Tpath->d.pt[Tpath->count++].Y = y;
  356. }
  357.  
  358. NCreateEndPath()
  359. {
  360.     Tpath = 0;
  361. }
  362.  
  363. NSetupNet(handle)
  364. TFhandle handle;
  365. {
  366.     TFSetup(handle,"net",NCreateNet,"name.s","rownum.i",0);
  367.     TFSetup(handle,"path",NCreatePath,"x.i","y.i",0);
  368.     TFSetup(handle,"endpath",NCreateEndPath,0);
  369. }
  370.  
  371. NWriteNet(f,net,n)
  372. FILE *f;
  373. Nnet *net;
  374. int n;
  375. {
  376. int i,j;
  377. Ngroup *path;
  378.  
  379.     if (!net) return;
  380.     if (n==0) {
  381.         fprintf(f,"\nnet schema \
  382. (\"name.s\" \"rownum.i\" /* angle */)\n");
  383.         fprintf(f,"path schema (\"x.i\" \"y.i\") endpath schema ()\n");
  384.     }
  385.     fprintf(f,"\nnet (");
  386.     NDumpString(f,net->name);
  387.     fprintf(f," %d",net->rownum);
  388.     fprintf(f," /* %c */",net->angle?net->angle:'0');
  389.     fprintf(f,")\n");
  390.  
  391.     for (i=0; i<net->pathlist.count; i++) {
  392.         path = net->pathlist.d.path[i];
  393.         fprintf(f,"    path");
  394.         for (j=0; j<path->count; j++) {
  395.             fprintf(f," (%d %d)",
  396.                 path->d.pt[j].X,path->d.pt[j].Y);
  397.         }
  398.         if (i<net->pathlist.count-1) fprintf(f," endpath ()");
  399.         fprintf(f,"\n");
  400.     }
  401. }
  402.  
  403. NBoundNet(net)
  404. Nnet *net;
  405. {
  406. int i,j;
  407. Ngroup *path;
  408.  
  409.     for (i=0; i<net->pathlist.count; i++) {
  410.         path = net->pathlist.d.path[i];
  411.         for (j=0; j<path->count; j++)
  412.             NAddBB(path->d.pt[j]);
  413.     }
  414. }
  415.  
  416. NPlotNet(net)
  417. Nnet *net;
  418. {
  419. int i,j;
  420. Ngroup *path;
  421.  
  422.     for (i=0; i<net->pathlist.count; i++) {
  423.         path = net->pathlist.d.path[i];
  424.         for (j=0; j<path->count-1; j++)
  425.             PLine(path->d.pt[j].X,path->d.pt[j].Y,
  426.                 path->d.pt[j+1].X,path->d.pt[j+1].Y);
  427.     }
  428. }
  429.  
  430. Nnet *
  431. NFindNet(base,name)
  432. Nbase *base;
  433. char *name;        /* name of the net to find */
  434. {
  435. int i;
  436.  
  437.     for (i=0; i<base->netlist.count; i++) {
  438.         if (strcmp(base->netlist.d.net[i]->name,name)==0)
  439.             return base->netlist.d.net[i];
  440.     }
  441.     return 0;
  442. }
  443.  
  444. NIFreeNet(net)
  445. Nnet *net;
  446. {
  447.     removep(&(Tbase->netlist),(char *)net);
  448.     NFreeNet(net);
  449. }
  450.  
  451. NFreeNet(net)
  452. Nnet *net;
  453. {
  454. extern int NFreeGroupOnly();
  455.  
  456.     if (net->name) tfree(net->name);
  457.     NFreeGroup(&(net->pathlist),NFreeGroupOnly);
  458.     NFreeGroupOnly(&(net->connlist));
  459.     tfree(net);
  460. }
  461.  
  462. NClearNetConns(net)
  463. Nnet *net;
  464. {
  465.     net->connlist.count = 0;
  466. }
  467.  
  468. /* Conn routines */
  469.  
  470. NBoundConn(){}
  471.  
  472. static
  473. plotx(x,y)
  474. {
  475. int size;
  476.  
  477.     size = NCurBase->textsize.Y;
  478.     PLine(x+size,y-size,x-size,y+size);
  479.     PLine(x+size,y+size,x-size,y-size);
  480. }
  481.  
  482. NPlotConn(conn)
  483. Nconn *conn;
  484. {
  485.     if (!Tflag['c']) return;
  486.         /* only plot connectors if the 'c' flag is set */
  487.     plotx(conn->apos.X,conn->apos.Y);
  488. }
  489.  
  490. Nconn *
  491. NCreateConn(boxname,connname,boxx,boxy,side,netname)
  492. char *boxname;        /* name of the box this conn goes to */
  493. char *connname;        /* connector name - only needs uniqeness in the box */
  494. int boxx,boxy;        /* connector coords relative to box origin */
  495. char *side;        /* which side (N,S,E,W) */
  496. char *netname;        /* name of the attached net */
  497. {
  498. Nconn *conn;
  499. char *s,*dirs;
  500.  
  501.     if (!connname || !*connname) {
  502.         fileerror(Thandle->tkhandle,"no name for connector");
  503.         return 0;
  504.     }
  505.     if (!boxname || !*boxname) {
  506.         fileerror(Thandle->tkhandle,"no box name for connector");
  507.         return 0;
  508.     }
  509.     if (!netname || !*netname) {
  510.         fileerror(Thandle->tkhandle,"warning: no net for connector");
  511.     }
  512.     if (!side) side="N";
  513.     conn = XCALLOC(Nconn,1);
  514.     conn->boxname = boxname;
  515.     conn->name = connname;
  516.     conn->pos.X = boxx;
  517.     conn->pos.Y = boxy;
  518.     dirs = "NSEW";
  519.     s = index(dirs,side[0]);
  520.     if (!s) conn->side = 0;
  521.     else conn->side = s-dirs;
  522.     conn->netname = netname;
  523.     insertp(&(Tbase->connlist),(char *)conn);
  524.     return conn;
  525. }
  526.  
  527. NSetupConn(handle)
  528. TFhandle handle;
  529. {
  530.     TFSetup(handle,"conn",NCreateConn,"boxname.s","name.s",
  531.         "x.i","y.i","side.s","netname.s",0);
  532. }
  533.  
  534. NWriteConn(f,conn,i)
  535. FILE *f;    /* file to write to */
  536. Nconn *conn;    /* the conn to write out */
  537. int i;        /* counter */
  538. {
  539.     if (!conn) return;
  540.     if (i==0) {    /* write out the schema the first time */
  541.         fprintf(f,"\nconn schema (\"boxname.s\" \"name.s\" \
  542. \"x.i\" \"y.i\" ");
  543.         if (Tflag['c']) {
  544.             fprintf(f,"\"ax.i\" \"ay.i\" ");
  545.         }
  546.         fprintf(f,"\"side.s\" \"netname.s\")\n\n");
  547.     }
  548.     fprintf(f,"conn (");
  549.     NDumpString(f,conn->boxname);
  550.     fputc(' ',f);
  551.     NDumpString(f,conn->name);
  552.     fprintf(f," %d %d",conn->pos.X, conn->pos.Y);
  553.     if (Tflag['c']) {
  554.         fprintf(f," %d %d",conn->apos.X, conn->apos.Y);
  555.     }
  556.     fprintf(f," \"%c\" ","NSEW"[conn->side]);
  557.     NDumpString(f,conn->netname);
  558.     fprintf(f,")\n");
  559. }
  560.  
  561. /* free a connector and remove it from the general conn list */
  562. NIFreeConn(conn)
  563. Nconn *conn;
  564. {
  565.     removep(&(Tbase->connlist),(char *)conn);
  566.     NFreeConn(conn);
  567. }
  568.  
  569. NFreeConn(conn)
  570. Nconn *conn;
  571. {
  572.     if (conn->name) tfree(conn->name);
  573.     if (conn->netname) tfree(conn->netname);
  574.     if (conn->boxname) tfree(conn->boxname);
  575.     tfree(conn);
  576. }
  577.  
  578. NPosConn(conn)    /* set the apos in a conn */
  579. Nconn *conn;
  580. {
  581.     if (conn->box) {
  582.         conn->apos.X = conn->box->origin.X + conn->pos.X;
  583.         conn->apos.Y = conn->box->origin.Y + conn->pos.Y;
  584.     }
  585. }
  586.  
  587. NLinkConn(conn)
  588. Nconn *conn;
  589. {
  590.     NLinkConnBox(conn);
  591.     NLinkConnNet(conn);
  592. }
  593.  
  594. NLinkConnBox(conn)
  595. Nconn *conn;
  596. {
  597. Nbox *box;
  598.  
  599.     box = NFindBox(Tbase,conn->boxname);
  600.     if (!box) {
  601.         printf("can't find box %s, connector %s\n",
  602.             conn->boxname, conn->name);
  603.     }
  604.     else {
  605.         conn->box = box;
  606.         insertp(&(box->connlist),(char *)conn);
  607.         NPosConn(conn);
  608.     }
  609. }
  610.  
  611. NLinkConnNet(conn)
  612. Nconn *conn;
  613. {
  614. Nnet *net;
  615.  
  616.     net = NFindNet(Tbase,conn->netname);
  617.     if (!net) {
  618.         net = NCreateNet(strsav(conn->netname),0);
  619.     }
  620.     conn->net = net;
  621.     insertp(&(net->connlist),(char *)conn);
  622. }
  623.  
  624. NUnLinkConnNet(conn)
  625. Nconn *conn;
  626. {
  627. Nnet *net;
  628.  
  629.     net = conn->net;
  630.     if (!net) return;
  631.     removep(&(net->connlist),(char *)conn);
  632.     conn->net = 0;
  633. }
  634.  
  635. /* Row routines */
  636.  
  637. NBoundRow(){}
  638. NPlotRow(){}
  639.  
  640. NCreateRow(rownum,size,pos)
  641. int rownum;
  642. int size;
  643. int pos;
  644. {
  645. Nrow *row;
  646.  
  647.     row = XCALLOC(Nrow,1);
  648.     row->rownum = rownum;
  649.     row->size = size;
  650.     row->pos = pos;
  651.     insertp(&(Tbase->rowlist),(char *)row);
  652. }
  653.  
  654. NSetupRow(handle)
  655. TFhandle handle;
  656. {
  657.     TFSetup(handle,"row",NCreateRow,"rownum.i","size.i","pos.i",0);
  658. }
  659.  
  660. NWriteRow(f,row,i)
  661. FILE *f;    /* file to write to */
  662. Nrow *row;    /* the row to write out */
  663. int i;        /* counter */
  664. {
  665.     if (!row) return;
  666.     if (i==0) {    /* write out the schema the first time */
  667.         fprintf(f,"\nrow schema (\"rownum.i\" \"size.i\" \
  668. \"pos.i\")\n\n");
  669.     }
  670.     fprintf(f,"row (%d %d %d", row->rownum, row->size, row->pos);
  671.     fprintf(f,")\n");
  672. }
  673.  
  674. NFreeRow(row)
  675. Nrow *row;
  676. {
  677.     tfree(row);
  678. }
  679.  
  680. /* globals routines */
  681.  
  682. static
  683. NDefaultGlobals(base)
  684. Nbase *base;
  685. {
  686.     base->textsize.X = 1;
  687.     base->textsize.Y = 1;
  688.     base->interrowspace = 3;
  689.     base->rowposspace = 2;
  690.     base->trackspace = 2;
  691.     base->rowdir = 'H';
  692.     base->label.s = 0;
  693. }
  694.  
  695. static
  696. NCreateGlobals(textsizex,textsizey,interrowspace,rowposspace,trackspace,
  697.     rowdir,label)
  698. int textsizex, textsizey;
  699. int interrowspace;
  700. int rowposspace;
  701. int trackspace;
  702. char *rowdir;
  703. char *label;
  704. {
  705.     Tbase->textsize.X = textsizex;
  706.     Tbase->textsize.Y = textsizey;
  707.     Tbase->interrowspace = interrowspace;
  708.     Tbase->rowposspace = rowposspace;
  709.     Tbase->trackspace = trackspace;
  710.     if (rowdir && (rowdir[0]=='V' || rowdir[0]=='H'))
  711.         Tbase->rowdir = rowdir[0];
  712. /*** else error */
  713.     Tbase->label.s = label;
  714. }
  715.  
  716. static
  717. NSetupGlobals(handle)
  718. TFhandle handle;
  719. {
  720.     TFSetup(handle,"globals",NCreateGlobals,"textsizex.i","textsizey.i",
  721.         "interrowspace.i","rowposspace.i","trackspace.i",
  722.         "rowdir.s","label.s",0);
  723. }
  724.  
  725. static
  726. NWriteGlobals(f,base)
  727. FILE *f;
  728. Nbase *base;
  729. {
  730.     fprintf(f,"\nglobals schema (\"textsizex.i\" \"textsizey.i\" \
  731. \"interrowspace.i\" \"rowposspace.i\" \"trackspace.i\" \
  732. \"rowdir.s\" \"label.s\")\n");
  733.     fprintf(f,"(%d %d %d %d %d \"%c\" ",
  734.             base->textsize.X, base->textsize.Y,
  735.             base->interrowspace, base->rowposspace,
  736.             base->trackspace, base->rowdir);
  737.     NDumpString(f,base->label.s);
  738.     fprintf(f,")\n");
  739. }
  740.  
  741. /* label routines */
  742.  
  743. /* ARGSUSED (so far!) */
  744. int        /* 1 if OK to go there */
  745. NCheckLabel(base,where)
  746. Nbase *base;
  747. int where;        /* compass code */
  748. {
  749.     return 0;    /*** not yet done! */
  750. }
  751.  
  752. NSetLabel(base)
  753. Nbase *base;
  754. {
  755. char *cp, *cp2;
  756. int xsize, ysize;
  757. int l;
  758.  
  759.     if (!base->label.s || !base->label.s[0]) return;
  760.     cp = base->label.s;
  761.     xsize = 0;
  762.     ysize = 0;
  763.     while (cp && *cp) {
  764.         cp2 = index(cp,'\n');
  765.         if (!cp2) l=strlen(cp);
  766.         else l=(cp2++)-cp;
  767.         if (l>xsize) xsize=l;
  768.         ysize++;
  769.         cp = cp2;
  770.     }
  771.     base->label.tsize.X = xsize;
  772.     base->label.tsize.Y = ysize;
  773.     if (NCheckLabel(base,SW)) {
  774.     }
  775.     else if (NCheckLabel(base,SE)) {
  776.     }
  777.     else {
  778.         base->label.origin.X = 0;    /*** not right! */
  779.         base->label.origin.Y = -(ysize+3)*base->textsize.Y;
  780.     }
  781. }
  782.  
  783. NBoundLabel(base)
  784. Nbase *base;
  785. {
  786. Npoint p;
  787.  
  788.     if (!base->label.s || !base->label.s[0]) return;
  789.     NAddBB(base->label.origin);
  790.     p.X = base->label.origin.X + (base->label.tsize.X+2)*base->textsize.X;
  791.     p.Y = base->label.origin.Y + (base->label.tsize.Y+2)*base->textsize.Y;
  792.     NAddBB(p);
  793. }
  794.  
  795. NPlotLabel(base)
  796. Nbase *base;
  797. {
  798. Npoint p;
  799.  
  800.     if (!base->label.s || !base->label.s[0]) return;
  801.     p.X = base->label.origin.X + (base->label.tsize.X+2)*base->textsize.X;
  802.     p.Y = base->label.origin.Y + (base->label.tsize.Y+2)*base->textsize.Y;
  803.     PBox(base->label.origin.X,base->label.origin.Y,p.X,p.Y);
  804.     if (!Tflag['T']) { /* 'T' flag turns off text */
  805.         PText(base->label.origin.X+base->textsize.X,
  806.             base->label.origin.Y+base->textsize.Y,
  807.             SW,base->label.s);
  808.     }
  809. }
  810.  
  811. /* Group routines */
  812.  
  813. NDumpGroup(f,group,funcp)
  814. FILE *f;
  815. Ngroup *group;
  816. int (*funcp)();
  817. {
  818. int i;
  819.     for (i=0; i<group->count ;i++)
  820.         (*funcp)(f,group->d.x[i],i);
  821. }
  822.  
  823. NDoGroup(group,funcp)
  824. Ngroup *group;
  825. int (*funcp)();
  826. {
  827. int i;
  828.  
  829.     for (i=0;i<group->count;i++)
  830.         (*funcp)(group->d.x[i]);
  831. }
  832.  
  833. NRDoGroup(group,funcp)
  834. Ngroup *group;
  835. int (*funcp)();
  836. {
  837. int i;
  838.  
  839.     for (i=group->count-1;i>=0;i--)
  840.         (*funcp)(group->d.x[i]);
  841. }
  842.  
  843. NClearGroup(group)
  844. Ngroup *group;
  845. {
  846.     group->count = group->alloc = 0;
  847.     group->d.x = 0;
  848. }
  849.  
  850. NFreeGroupOnly(group)
  851. Ngroup *group;
  852. {
  853.     if (group->d.x)
  854.         tfree(group->d.x);
  855.     NClearGroup(group);
  856. }
  857.  
  858. NFreeGroup(group,funcp)
  859. Ngroup *group;
  860. int (*funcp)();
  861. {
  862.     NDoGroup(group,funcp);
  863.     NFreeGroupOnly(group);
  864. }
  865.  
  866. /* Base routines */
  867.  
  868. NSetBase(base)
  869. Nbase *base;
  870. {
  871.     Tbase = base;
  872. }
  873.  
  874. NFreeNetwork(base)    /* deallocates everything */
  875. Nbase *base;
  876. {
  877.     if (!base) return;
  878.     NFreeGroup(&(base->boxlist),NFreeBox);
  879.     NFreeGroup(&(base->netlist),NFreeNet);
  880.     NFreeGroup(&(base->connlist),NFreeConn);
  881.     NFreeGroup(&(base->rowlist),NFreeRow);
  882.     tfree(base);
  883. }
  884.  
  885. Nbase *
  886. NReadNetwork(filename)
  887. char *filename;
  888. {
  889. TFhandle handle;
  890.  
  891.     Tbase = XCALLOC(Nbase,1);
  892.     Thandle = handle = TFInit(filename);
  893.     if (!handle) {
  894.         printf("can't open file %s",filename);
  895.         return 0;
  896.     }
  897.     NDefaultGlobals(Tbase);
  898.     NSetupGlobals(handle);
  899.     NSetupBox(handle);
  900.     NSetupNet(handle);
  901.     NSetupConn(handle);
  902.     NSetupRow(handle);
  903.     TFScan(handle);
  904.     TFDone(handle);
  905.     NDoGroup(&(Tbase->connlist),NLinkConn);
  906.         /* put together the box/conn/net links */
  907.     return Tbase;
  908. }
  909.  
  910. int        /* 0 if error */
  911. NRead(filename)
  912. char *filename;
  913. {
  914. Nbase *newbase;
  915.  
  916.     newbase = NReadNetwork(filename);
  917.     if (newbase) {
  918.         NFreeNetwork(NCurBase);
  919.         NCurBase = newbase;
  920. /* Note that Tbase==NCurBase at this point, which is important! */
  921.         return 1;        /* all OK */
  922.     }
  923.     return 0;    /* no go */
  924. }
  925.  
  926. int
  927. NWrite(filename)
  928. char *filename;
  929. {
  930. FILE *f;
  931. int t;
  932.  
  933.     if (!NCurBase) {
  934.         printf("no data to write");
  935.         return 0;
  936.     }
  937.     if (strcmp(filename,"stdout")==0) f=stdout;
  938.     else if (strcmp(filename,"stderr")==0) f=stderr;
  939.     else f=fopen(filename,"w");
  940.     if (!f) {
  941.         printf("can't open file %s for output\n",filename);
  942.         return 0;
  943.     }
  944.     fprintf(f,"/* TF netlist */\n");
  945.         /*** should add date, etc. */
  946.     NWriteGlobals(f,NCurBase);
  947.     NDumpGroup(f,&(NCurBase->boxlist),NWriteBox);
  948.     NDumpGroup(f,&(NCurBase->netlist),NWriteNet);
  949.     NDumpGroup(f,&(NCurBase->connlist),NWriteConn);
  950.     NDumpGroup(f,&(NCurBase->rowlist),NWriteRow);
  951.     fprintf(f,"/* end */\n");
  952.     if (f==stdout || f==stderr) fflush(f);
  953.     else {
  954.         t = ferror(f) || fclose(f);
  955.         if (t) {
  956.             printf("error closing file %s\n",filename);
  957.             return 0;
  958.         }
  959.     }
  960.     return 1;
  961. }
  962.  
  963. static int
  964. NDoPlot()
  965. {
  966.     if (!(PInit(BBlow.X,BBlow.Y,BBhigh.X,BBhigh.Y))) {
  967.         printf("can't init plot\n");
  968.         return 0;
  969.     }
  970.     PTextSize(NCurBase->textsize.X,NCurBase->textsize.Y);
  971.             /* specify the size of text */
  972.     NDoGroup(&(NCurBase->boxlist),NPlotBox);
  973.     NDoGroup(&(NCurBase->netlist),NPlotNet);
  974.     NDoGroup(&(NCurBase->connlist),NPlotConn);
  975.     NDoGroup(&(NCurBase->rowlist),NPlotRow);
  976.     NPlotLabel(NCurBase);
  977.     PDone();
  978.     return 1;
  979. }
  980.  
  981. static int
  982. NBoundPlot()
  983. {
  984.     if (!NCurBase) {
  985.         printf("no data to plot");
  986.         return 0;
  987.     }
  988.     NInitBB();
  989.     NDoGroup(&(NCurBase->boxlist),NBoundBox);
  990.     NDoGroup(&(NCurBase->netlist),NBoundNet);
  991.     NDoGroup(&(NCurBase->connlist),NBoundConn);
  992.     NDoGroup(&(NCurBase->rowlist),NBoundRow);
  993.     NSetLabel(NCurBase);
  994.     NBoundLabel(NCurBase);
  995.     return 1;
  996. }
  997.  
  998. int
  999. NPlot(ptype,filename)
  1000. char *ptype;
  1001. char *filename;
  1002. {
  1003.     if (!NBoundPlot()) return 0;
  1004.     if (!(PSetType(ptype,filename))) { return 0; }
  1005.     return NDoPlot();
  1006. }
  1007.  
  1008. static int
  1009. NPartPlot(ptype,filename,xnum,ynum,lx,ly,hx,hy)
  1010. char *ptype;
  1011. char *filename;
  1012. int xnum,ynum;        /* repetition numbers */
  1013. double lx,ly,hx,hy;
  1014. {
  1015. char nbuf[2000];
  1016.  
  1017.     sprintf(nbuf,"%s_%d_%d",filename,xnum,ynum);
  1018.     if (!(PSetType(ptype,nbuf))) { return 0; }
  1019.     PSetWindow(lx,ly,hx,hy);
  1020.     return NDoPlot();
  1021. }
  1022.  
  1023. int
  1024. NPlot4(ptype,filename)
  1025. char *ptype;
  1026. char *filename;
  1027. {
  1028.     return NPlotXY(ptype,filename,2,2);
  1029. }
  1030.  
  1031. #define MAXPLOTREP 64
  1032.  
  1033. int
  1034. NPlotXY(ptype,filename,xnum,ynum)
  1035. char *ptype;
  1036. char *filename;
  1037. int xnum,ynum;
  1038. {
  1039. int x,y;
  1040. double xinc, yinc;
  1041. double xbase,ybase;
  1042.  
  1043.     if (xnum<=0 || ynum<=0 || xnum>MAXPLOTREP || ynum>MAXPLOTREP) {
  1044.         printf("Bad repeat number\n");
  1045.         return 0;
  1046.     }
  1047.     if (!NBoundPlot()) return 0;
  1048.     xinc = 1.0/(double)xnum;
  1049.     yinc = 1.0/(double)ynum;
  1050.     xbase = 0.;
  1051.     for (x=0; x<xnum; x++) {
  1052.         ybase = 0.;
  1053.         for (y=0; y<ynum; y++) {
  1054.             if (!NPartPlot(ptype,filename,x,y,
  1055.                 xbase,ybase,xbase+xinc,ybase+yinc)) return 0;
  1056.             ybase += yinc;
  1057.         }
  1058.         xbase += xinc;
  1059.     }
  1060.     return 1;
  1061. }
  1062.  
  1063. char *
  1064. TFlags(flags)
  1065. char *flags;
  1066. {
  1067. int i;
  1068. char *cp, *np;
  1069.  
  1070.     if (!flags) flags="";
  1071.     switch (flags[0]) {
  1072.     case '=':
  1073.         for (i=0; i<Tflagcount; i++) Tflag[i]=0;
  1074.         /* FALL THROUGH */
  1075.     case '+':
  1076.         for (cp=flags+1; *cp; cp++)
  1077.             Tflag[*cp] = 1;
  1078.         break;
  1079.     case '-':
  1080.         for (cp=flags+1; *cp; cp++)
  1081.             Tflag[*cp] = 0;
  1082.         break;
  1083.     case '?':
  1084.     case '\0':
  1085.         break;        /* just return the value */
  1086.     case 'h':
  1087.         TFlagsHelp();
  1088.         break;
  1089.     default:
  1090.         break;    /*** should output error message */
  1091.     }
  1092.     for (np=Tflagr, i=0; i<Tflagcount; i++)
  1093.         if (Tflag[i]) *np++ = i;
  1094.     *np = '\0';
  1095.     return Tflagr;
  1096. }
  1097.  
  1098. TFlagsHelp()
  1099. {
  1100.     printf("TFlags [+-=?][flagchars]\n");
  1101.     printf("c  enables plotting of connectors\n");
  1102.     printf("f  enables plotting of feedthough boxes\n");
  1103.     printf("l  enables label where text normally goes in boxes\n");
  1104.     printf("m  memory debugging - makes free not do anything\n");
  1105.     printf("T  disables normal text in boxes\n");
  1106. }
  1107.  
  1108. /* end */
  1109.